
import Map from 'ol/Map'
import View from 'ol/View'
import { fromLonLat } from 'ol/proj'
import MousePosition from 'ol/control/MousePosition';
import { Coordinate } from 'ol/coordinate';
import { transformExtent } from "ol/proj";

import olGeoJson_bordLine_annotation from "./mapComponent/layers/olGeoJson_bordLine_annotation";  // 边界线+注记类库
import layerMgr from "./mapComponent/layers/index";  // 图层管理类库
import Olmarker_manager from "./mapComponent/layers/olmarker_manager"; // 标记点管理类
import OlWindy_manager from "./mapComponent/layers/olWindy_manager"; // 风场管理类
import OlGeoTiff from "./mapComponent/layers/olGeoTiff";  // geotiff管理类
import OlImageManger from "./mapComponent/layers/olImageManger";  // 处理图片管理类
import GrayMapColor from "./mapComponent/layers/grayMapColor";  // 灰度图映射管理类
import MouseEvent from "./mapComponent/layers/mouseEvent";  // 事件管理器
import BaseMap from "./mapComponent/layers/baseMap"; // 地图底层图层管理器
import Animation from "./mapComponent/layers/animation"; // 地图动画管理器
import TargetPlayback from "./mapComponent/layers/TargetPlayback ";
import OlUtils from "./utlis/olUtils";
import { loadShapefiles } from "./mapComponent/layers/olShapefiles";
import { mainInterval } from './config';
import { Feature } from 'ol';
import { Polygon } from 'ol/geom';
import { Fill, Stroke, Style } from 'ol/style';
import { Vector as VectorLayer } from 'ol/layer';
import { Vector as VectorSource } from 'ol/source';
import qd_city1 from "../../public/district/青岛行政区划/qd_market.geojsonl1.json";
import qd_city2 from "../../public/district/青岛行政区划/qd_market.geojsonl2.json";
import qd_city3 from "../../public/district/青岛行政区划/qd_market.geojsonl3.json";
import qd_city4 from "../../public/district/青岛行政区划/qd_market.geojsonl4.json";
import qd_city5 from "../../public/district/青岛行政区划/qd_market.geojsonl5.json";
import qd_city6 from "../../public/district/青岛行政区划/qd_market.geojsonl6.json";
import qd_city7 from "../../public/district/青岛行政区划/qd_market.geojsonl7.json";
import qd_city8 from "../../public/district/青岛行政区划/qd_market.geojsonl8.json";
import qd_city9 from "../../public/district/青岛行政区划/qd_market.geojsonl9.json";
import qd_city10 from "../../public/district/青岛行政区划/qd_market.geojsonl10.json";
import qd_city11 from "../../public/district/青岛行政区划/qd_city.geojsonl.json";
// import qd_city2 from "../../public/district/青岛行政区划/qd_county.geojsonl.json";
// import qd_city3 from "../../public/district/青岛行政区划/qd_retc_nc.geojsonl.json";
// import qd_city4 from "../../public/district/青岛行政区划/qd_retc.geojsonl.json";
// import qd_city5 from "../../public/district/青岛行政区划/qd_retc.geojsonl.json";
// 青岛边界新数据

/**
 * 
 * 对地图openlayers封装库
 * 此类调用说明： 
 * 1.正常引入
 * 2.获取单例 ：如let olService = OpenLayersMap.getInstance()
 * 3.正常 通过 olService 调用函数使用
 * 
 */
interface MoveData {
    time: number; // 时间戳
    coordinates: [number, number]; // 坐标 [longitude, latitude]
    name: string; // 模型名称
    heading: number
}
let _this
export default class OpenLayersMap {
    private static instance: OpenLayersMap | null = null;  // 私有实体
    private map: Map;

    private bordLine_annotation = new olGeoJson_bordLine_annotation()  // 实例化边界线和注记
    private layer_manager: layerMgr // 图层管理类
    private olmarker_manager: Olmarker_manager // 标记点管理类
    private olWindy_manager: OlWindy_manager // 风场管理类
    private olGeoTiff: OlGeoTiff // geotiff管理类
    private olImageManger: OlImageManger  // 图片管理类
    private olGrayMapColor: GrayMapColor // 灰度图映射类
    private olMouseEvent: MouseEvent // 灰度图映射类
    private olBaseMap: BaseMap; // 地图底层图层
    private olAnimation: Animation;
    private olTargetPlayback: TargetPlayback
    private olUtils: OlUtils

    private intervalCount = 0
    private interval = null


    private images = ["../../public/Image/leida/Z_RADR_I_Z9532_20241013113023_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013113609_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013114154_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013114740_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013115325_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013115910_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013120456_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013121041_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013121627_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013122212_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013122757_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013123343_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013123928_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013124513_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013125058_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013125644_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013130229_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013130814_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013131400_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013131945_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013132530_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013133116_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013133701_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013134247_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013134832_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013135418_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013140003_O_DOR_SAD_CAP_FMT.png",
        "../../public/Image/leida/Z_RADR_I_Z9532_20241013140549_O_DOR_SAD_CAP_FMT.png",
    ]


    // 私有构造函数，确保单例
    private constructor() {


    }

    /** 
     * 获取单实例的静态方法
     * 
     */
    public static getInstance(): OpenLayersMap {
        if (!OpenLayersMap.instance) {
            OpenLayersMap.instance = new OpenLayersMap()

        }
        return OpenLayersMap.instance
    }

    /**
     * 初始化地图
     * @param target 容器
     * @param options 初始化的中心点和地图级别
     */
    public async initMap(target: HTMLElement, options: { center: [number, number], zoom: number }): Promise<Map> {
        // const response = await fetch('../../public/Shapefile/gaopao/');
        // const data = await response.text();
        if (!this.map) {
            // 创建二维地图实体
            this.map = new Map({
                target,
                layers: [],
                view: new View({
                    center: fromLonLat(options.center),
                    zoom: options.zoom, // 初始缩放级别
                    minZoom: 0, // 最小缩放级别
                    maxZoom: 20,
                    projection: 'EPSG:3857',
                    extent: transformExtent([-180, -90, 180, 90], 'EPSG:4326', 'EPSG:3857')// 全世界的范围
                    // maxZoom: 13
                }),
                controls: []
            })


            // 实例化类库
            this.layer_manager = new layerMgr(this.map)// 实例化图层管理
            this.olmarker_manager = new Olmarker_manager(this.map)// 实例化标记点管理类
            this.olWindy_manager = new OlWindy_manager(this.map) // 实例化风场管理类
            this.olGeoTiff = new OlGeoTiff() //实例化geotiff管理类
            this.olImageManger = new OlImageManger() // 实例化图片管理类
            this.olGrayMapColor = new GrayMapColor(this.map)
            this.olBaseMap = new BaseMap(this.map)
            this.olAnimation = new Animation(this.map)
            this.olUtils = new OlUtils()
            this.olTargetPlayback = new TargetPlayback(this.map, this.callPlayBack, this.layer_manager)


            // 添加控件
            this.getMouseMoveInfo();  // ol控件（鼠标移动获取坐标信息并展示）


            //其它行为
            // this.callPlay("../../public/2024山东飞机轨迹/NM_B3913_202410131936.CSV", '测试起飞')
            this.changeBaseMap('T_Vector')

            this.openRadar()
            const districtPath = [qd_city1,qd_city2,qd_city3,qd_city4,qd_city5,qd_city6,qd_city7,qd_city8,qd_city9,qd_city10,qd_city11]
            this.create_boundary(districtPath,'qingdaoDistrictPath',true)   // 创建青岛边界线
            _this = this

        }
        return this.map
    }

    /**
     * 鼠标移动获取坐标信息
     */
    private getMouseMoveInfo() {
        // 添加ol自带鼠标显示坐标信息配置
        var mousePositionControl = new MousePosition({
            coordinateFormat: (coordinate: Coordinate | []) => {
                let coor: Array<any> = []
                let cooritem: Coordinate = coordinate
                coor.push(cooritem[0].toFixed(4), cooritem[1].toFixed(4))

                return coor.toString()
            },
            projection: 'EPSG:4326', // 设置坐标系为 WGS 84  
            className: 'custom-mouse-position', // 自定义样式类名（可选）  
            target: document.getElementById('mouse-position') as HTMLElement  // 如果需要自定义显示位置，可以指定一个 DOM 元素作为目标容器  
        });

        // 将控件添加到地图中（如果不指定 target，则默认添加到地图的右上角）  
        this.map.addControl(mousePositionControl);
    }

    /**
     * 切换底图图层
     * @param typeName T_Vector  天地图矢量图层，T_Image 天地图影像图层
     */
    public changeBaseMap(typeName: string) {
        this.olBaseMap.changeBaseMap(typeName)
    }

    /**
     * 跳跃至提供的坐标点
     * @param coordinate [经度,纬度]
     * @param duration 过渡时间 /s
     *  @param zoom 高度
     */
    public jumpToLocation(coordinate: Array<any>, duration: number, zoom: number = 3.6) {
        this.map.getView().animate({
            center: coordinate,
            duration,
            zoom: zoom
        })
    }



    /**
     * 创建边界线
     * @param geoJsonArray geoJSON数组
     * @param layerId 图层Id
     */
    public create_boundary(geoJsonArray: Array<any>, layerId: string, isAllowDelete: boolean, levelOptions?: { minLevel?: number, maxLevel?: number }) {
        let vectorLayer = this.bordLine_annotation.createBoundaryLayer(geoJsonArray, layerId, levelOptions)
        vectorLayer.setZIndex(2)
        this.addLayer(vectorLayer, layerId, isAllowDelete)
    }


    /**
     * 创建注记
     * @param geoJsonArray geoJSON数组
     * @param layerId 图层Id
     */
    public create_annotation(geoJsonArray: Array<any>, layerId: string, isAllowDelete: boolean, levelOptions?: { minLevel?: number, maxLevel?: number }) {
        let vectorLayer = this.bordLine_annotation.createLabelLayer(geoJsonArray, layerId, levelOptions)
        // debugger
        this.addLayer(vectorLayer, layerId, isAllowDelete)
    }

    /**
     * 创建标记点
     * @param marker 标记点对象
     */
    public createMarker(marker: any) {
        this.olmarker_manager.addMarker(marker)
    }

    /**
     * 批量创建标记点
     * @param markers 数组标记点对象
     */
    public createMarkers(markers: Array<any>, layerId: string, isAllowDelete: boolean) {
        const vectorLayer = this.olmarker_manager.addMarkers(markers)
        this.addLayer(vectorLayer, layerId, isAllowDelete)
    }

    /**
     * 
     * @param id 图层id
     * @param url  访问服务的url
     * @param layerName  访问的图层名称
     * @param isAllowDelete  是否可以删除图层
     */
    public async createGeoTIFF(id: string, url: string, layerName: string, isAllowDelete: boolean) {
        const params = {
            'LAYERS': layerName, // 替换为你的图层名称  
            'TILED': true,
            'FORMAT': 'image/png'

        }
        const geoLayer = this.olGeoTiff.initWms(url, params)
        // 添加到图层
        await this.addLayer(geoLayer, id, isAllowDelete)
    }


    /**
     * 批量添加图片
     * @param id 图层id
     * @param imageDatas  imageUrl: string(图片文件必填，保持key名称一致),   extent?: [number, number, number, number]（x渲染范围，默认全球）,    imageProjection?: string（4326or3758）
     */
    public async createImages(id: string, imageDatas: Array<any>, isAllowDelete: boolean) {
        const ImageLayer = this.olImageManger.addImageLayers(imageDatas)
        await this.addLayer(ImageLayer, id, isAllowDelete)
    }


    /**
     * 添加图片
     * @param id 图层id
     * @param imageDatas  imageUrl: string(图片文件必填，保持key名称一致),   extent?: [number, number, number, number]（x渲染范围，默认全球）,    imageProjection?: string（4326or3758）
     */
    public async createImage(id: string, imageDatas: string, isAllowDelete: boolean) {
        const ImageLayer = this.olImageManger.addImageLayer(imageDatas)
        await this.addLayer(ImageLayer, id, isAllowDelete)
    }

    /**
     * 
     * @param id 图层id
     * @param windData 风场数据
     * @param isAllowDelete 是否可以删除图层
     */
    public createWindy(id: string, windData: any, isAllowDelete: boolean) {
        const windLayer = this.olWindy_manager.initializationWindLayer(windData)
        this.addLayer(windLayer, id, isAllowDelete)
    }

    /**
     * 将颜色映射到灰度图
     * @param id 图层id
     * @param colorMapData 图例信息
     * @param isAllowDelete 是否可以删除图层
     */
    public grayToColor(id: string, url: string, colorMapData: Array<any>, isAllowDelete: boolean) {
        this.olGrayMapColor.loadTiff(url, colorMapData).then(res => {
            this.addLayer(res, id, isAllowDelete)
        })
    }

    public callPlay(url: string, name: string) {
        let layer;
        this.olUtils.loadCSV(url).then(res => {
            const moveData: MoveData[] = res
            layer = this.olTargetPlayback.initCallPlayData(moveData, name)
            layer.forEach(item => {
                this.addLayer(item.data, item.name, true)
            });

        })

        setTimeout(() => {
            this.olTargetPlayback.startPlayback()
        }, 2000);

    }
    public callPlayBack() {
        _this.intervalCount++
        _this.images.forEach(image => {
            if (_this.images[_this.intervalCount] == image) {
                _this.layer_manager.setVisble(true, image)
            } else {
                _this.layer_manager.setVisble(false, image)
            }

            if (_this.intervalCount >= _this.images.length - 1) {
                _this.intervalCount = 0
            }
        })
    }

    public stopCallPlay() {
        this.olTargetPlayback.stopPlayback()
    }

    public clearCallBackData() {
        return this.olTargetPlayback.clearData()
    }

    /**
     * 加载射界
     * @param type gaopao , huojian
     */
    public async loadShapefiles(type: string) {
        loadShapefiles(`/Shapefile/${type}.zip`).then(res => {
            this.addLayer(res, type, true)
        })


    }
    /**
     * 关闭射界
     * @param type gaopao , huojian
     */
    public removeShapeFile(type: string) {
        this.layer_manager.removeLayer(type)

    }

    public closeRadar() {
        this.destory()
        this.images.forEach(image => {
            this.layer_manager.removeLayer(image)
        })

    }

    public openRadar() {
        this.images.forEach((item, index) => {
            this.createImage(item, item, true)

        })
        setTimeout(() => {
            this.images.forEach((item, index) => {
                if (index == 0) {
                    this.layer_manager.setVisble(true, item)
                } else {
                    this.layer_manager.setVisble(false, item)
                }
            })
        }, 1000);

    }

    public isTrackedModel(isTracked: boolean) {
        this.olTargetPlayback.isTracked = isTracked
    }

    /** 注册鼠标单击事件 */
    public createSingleClickEvent(mouseHandleCallBack: Function, isPc: boolean) {
        this.olMouseEvent = new MouseEvent(this.map, mouseHandleCallBack, isPc)
    }

    /** 销毁单击事件 */
    public destroySingleClick() {
        this.olMouseEvent.destroyEvent()
    }


    public test(id: string) {
        // const layer = this.olGeoTiff.fetchTifData("")
        // this.addLayer(layer, id, true)
    }

    /**
     * 添加图层
     * @param layer 图层实例
     */
    public addLayer(layer: any, layerId: string, isAllowDelete: boolean): void {
        this.layer_manager.addLayer(layer, layerId, isAllowDelete)

    }

    /**
     * 根据id移除图层
     * @param layerId 图层id
     */
    public clearLayer(layerId: string): void {
        this.layer_manager.removeLayer(layerId)

    }


    /**
     * 移除所有图层
     */
    public clearAllLayer() {
        this.layer_manager.removeAllLayer()
    }

    public destory() {
        clearInterval(this.interval)
    }

    public addTrack() {
        // interface TrackPoint {  
        //     id: number;  
        //     lon: number;  
        //     lat: number;  
        //     time: number; // Unix timestamp  
        //     imageUrl?: string; // Optional image URL for close-up view  
        //   }  

        //   const trackPoints: TrackPoint[] = [  
        //     { id: 1, lon: -74.006, lat: 40.7128, time: Date.now() - 10000, imageUrl: "../../../public/pic/routePlanning/雷暴 (2).png" },  
        //     { id: 2, lon: -73.9855, lat: 40.7488, time: Date.now() - 5000, imageUrl:"../../../public/pic/routePlanning/雷暴 (2).png" }, 
        //   ];
        //   this.olmotion_track.addPoints(trackPoints)
        // this.olmotion_track.addPoint(1,  
        //     [0, 0],  
        //     { name: 'Point 1' },  
        //     [  
        //       [0, [0, 0]],  
        //       [1000, [1, 1]],  
        //       [2000, [2, 2]],  
        //     ] )
    }
}
